Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

Система отслеживания — II (Дмитрий Котеров)
Author Message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Sat Apr 05, 2003 2:08 am ()
   Post subject: Система отслеживания — II
Reply with quote

Переписал бОльшую часть кода. Новые возможности:

1. Показывается количество новых и измененных топиков (на главной странице).
2. В выпадающем списке быстрого перехода на форум (обычно сверху справа) эта информация также доступна.
3. Если какой-то форум постоянно «краснеет», хотя пользователь уже потерял к нему интерес, он может от него отказаться — на шлавной странице флажки и кнопка «Не следить».
4. Пометка выборочных форумов как прочитанных.
5. На JavaScript: после клика на ссылку на топик в форуме ссылка перечеркивается. Это очень удобно, если измененных тем много, а топики открываются в IE по Shift+Click (в новом окне).
6. Поправил глюк в HTML, из-за которого форма добавления сообщения неправильно отображалась в NN и Mozilla.
7. После того, как все темы в каком-то форуме посещены, он автоматом гаснет на главной странице.
8. Все это дело кэшируется, чтобы не тормозило (и почти не тормозит).

В ближайшей перспективе: расширить Поиск возможностью «Найти измененные и новые топики» (будет ссылка с главной страницы). Сейчас БД сильно избыточна с целью сделать процесс такого поиска возможным (раньше нельзя было, тормозило очень).

P.S.
Насчет ЧПУ: я их с тех пор так и не включил, из-за двух причин:
1. Тормозят они. Надо делать с кэшированием (чтобы загружать все данные одним запросом, а не пятидесятью), что, в принципе, не так уж и сложно.
2. Чтобы глюки не наслаивались друг на друга.
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Mon Apr 07, 2003 12:36 am (спустя 1 день 22 часа 27 минут)
   Post subject:
Reply with quote

Заработала кнопка «Найти: непрочитанные» сообщения. Теперь вместо того, чтобы шастать из форума в форум, вы можете просто на главной странице открыть все новые и обновленные темы в одном окне и ходить по ним.

Естественно, поиск ведется среди топиков, которые находятся в «отслеживаемых» форумах. Напоминаю, что для того, чтобы пометить форум, как отслеживаемый, нужно либо прочитать хотя бы один топик в нем, либо же пометить его на главной странице флажком и нажать «Следить».

Данная возможность очень рекомендована к применению.
Back to top
View user's profile Send private message Send e-mail
claster
Участник форума



Joined: 20 Mar 2003
Posts: 25
Карма: 0
   поощрить/наказать


PostPosted: Mon Apr 07, 2003 11:15 am (спустя 10 часов 39 минут)
   Post subject:
Reply with quote

Однозначно стало удобней.
Только почему то после трех дней не посещения, все темы отмечены как прочитанные.
Но в форумах есть темы которые я не читал.
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Mon Apr 07, 2003 9:39 pm (спустя 10 часов 24 минуты)
   Post subject:
Reply with quote

Это издержки перехода к новой системе, к сожалению. Больше такого не будет.

Сегодня поправил еще несколько глюков, которые возникали при переносе тем в другие форумы. Теперь все должно работать корректно.
Back to top
View user's profile Send private message Send e-mail
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Fri Dec 12, 2003 9:44 pm (спустя 8 месяцев 5 дней 4 минуты)
   Post subject:
Reply with quote

Дмитрий Котеров:
Я помню, что в системе отслеживания не создается очень много записей - скорее всего одной записи соответствует одна непрочитанная тема. Но каким образом "инвертировать" эти записи - то есть записывать именно непрочитанные темы, а не прочитанные ? Честно говоря, мне ничего в голову не приходит по поводу того, каким образом реализована Ваша система статистики, и как она реализована в других форумах (скажем в wwwthreads очень похожая система).

Можете хотя бы немного описать реализацию Вашей системы, а то просто ничего на ум не приходит :(...
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Fri Dec 12, 2003 9:47 pm (спустя 2 минуты)
   Post subject:
Reply with quote

yUAC wrote:
 одной записи соответствует одна непрочитанная тема.
Наоборот. Новая запись создается только тогда, когда пользователь в топик заходит. Так что если в форуме миллион топиков, а пользователь зашел за все время только в сотню, в БД будет всего 100 записей.

Как реализуется — для каждого форума хранится дата последнего его «друксования».
Back to top
View user's profile Send private message Send e-mail
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Fri Dec 12, 2003 9:49 pm (спустя 2 минуты)
   Post subject:
Reply with quote

Дмитрий Котеров:
Хм, а как же быть с кнопкой "отметить как непрочитанные" ?

P.S. Я "прочел" практически все топики, на мое имя хранится около 1000 записей ?
P.P.S. Как быть с только что зарегистрированными пользователями ? Для них все темы считаются "новыми", или как ?
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Fri Dec 12, 2003 10:25 pm (спустя 35 минут)
   Post subject:
Reply with quote

yUAC wrote:
Хм, а как же быть с кнопкой "отметить как непрочитанные" ?
Эта кнопка устанавливает дату последнего друксования для форума равной текущей.
yUAC wrote:
Я "прочел" практически все топики, на мое имя хранится около 1000 записей ?
А как же иначе? Если одна из этих тем изменится, Вы тут же увидите это.
Для закрытых тем запись удаляется, но только после просмотра Вами этой темы.
yUAC wrote:
Как быть с только что зарегистрированными пользователями ? Для них все темы считаются "новыми", или как ?
Нет, новые — это те, что создались после последнего друксования, и для которых нет записи о просмотре. Все просто. Но SQL-запрос, который все это выбирает, немал.
Back to top
View user's profile Send private message Send e-mail
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Fri Dec 12, 2003 10:33 pm (спустя 8 минут)
   Post subject:
Reply with quote

Дмитрий Котеров wrote:
Эта кнопка устанавливает дату последнего друксования для форума равной текущей.
То есть если на форуме дата друксования равна N, то записей о просмотре предыдущих тем может и не быть, они в любом случае считаются "прочитанными" ?
Если я правильно понял, то можно смело удалять все записи о просмотре тем в данном форуме после нажания "отметить все как прочитанные" ? (наверняка такого не делается)
Дмитрий Котеров wrote:
А как же иначе? Если одна из этих тем изменится, Вы тут же увидите это.
В таком случае, я думаю, можно провести "оптимизацию", и если в форуме нет ни одного "непрочитанного" сообщения, проводить действия, аналогичные нажатию на кнопку "пометить все как прочитанные" (с удалением всех "ненужных" записей) ?
Дмитрий Котеров wrote:
Но SQL-запрос, который все это выбирает, немал.
Можете продемонстрировать, пожалуйста (если это не большая тайна) ;) ?
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Sat Dec 13, 2003 1:57 am (спустя 3 часа 23 минуты)
   Post subject:
Reply with quote

yUAC wrote:
Если я правильно понял, то можно смело удалять все записи о просмотре тем в данном форуме после нажания "отметить все как прочитанные" ? (наверняка такого не делается)
Вы поняли неправильно. Удалять в идеале пометки вообще никогда нельзя (разве что при посещении закрытой темы). Представьте, что Вы задруксовали форум, а завтра изменилась тема, которая Вам интересна, но была вчера задруксована.

Если я, конечно, ничего не путаю.
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Sat Dec 13, 2003 2:00 am (спустя 3 минуты)
   Post subject:
Reply with quote

yUAC wrote:
В таком случае, я думаю, можно провести "оптимизацию"
Можно. Правда, удалять ничего нельзя, но вот зато сдвигать метку друксования — можно, это сэкономит быстродействие.
yUAC wrote:
Можете продемонстрировать
Одна из функций:
Code (php): скопировать код в буфер обмена
// Returns states for forums with id in array $fids.
// Returns array(
// Returns array(
//   fid => array(
//     fid => ...,
//     topic_takepart => ...,  - does the user take part in this topic
//     topic_modified => ...,  - is the topic modified
//     topic_lastvisit => ...  - time of last user visit.
//   ), ...
// )
function getForumsStates($fids=false)
{
        $sql_fids = is_array (www.php.net/is_array)($fids)? make_sql("wf.fid in (?)", $fids) : "1";
                // First fetch all available info.
        $sql = make_sql("
                        SELECT wf.*
                        FROM "
.MOD_WATCHER_TABLE_F." wf
                        WHERE wf.uid=? AND ($sql_fids)
                "
,
                $this->uid
        );
        if (!($result = $this->db->sql_query($sql)))
                message_die(GENERAL_ERROR, 'Could not select forums states', '', __LINE__, __FILE__, $sql);
        $dirty = $status = array (www.php.net/array)();
        while ($row = $this->db->sql_fetchrow($result)) {
                if ($row['nnew'] < 0 || $row['nmodified'] < 0) $dirty[] = $row['fid'];
                $status[$row['fid']] = $row;
        }
                // Now in $dirty is not solved forums.
        if (count (www.php.net/count)($dirty)) {
                // 1. Select forums with modified-watched topics.
                $sql = make_sql("
                                SELECT
                                        wt.fid                  as fid,
                                        count(wt.modified)      as nmodified
                                FROM
                                        "
.MOD_WATCHER_TABLE_T." wt
                                WHERE
                                        wt.uid=? AND wt.fid IN (?) AND
                                        wt.modified
                                GROUP BY
                                        wt.fid
                        "
,
                        $this->uid, $dirty
                );
                if (!($result = $this->db->sql_query($sql)))
                        message_die(GENERAL_ERROR, 'SQL error', '', __LINE__, __FILE__, $sql);
                while ($row = $this->db->sql_fetchrow($result)) {
                        $fid = $row['fid'];
                        if (!isset (www.php.net/isset)($status[$fid])) continue;
                        $status[$fid]['nmodified'] = $row['nmodified'];
                }
                        echo (www.php.net/echo) "<hr>1: $sql<hr>";
                        // 2. Count all topics created since last mark EXCEPT watched.
                $sql = make_sql("
                        SELECT
                                w.fid              as fid,
                                count(t.topic_id)  as nnew
                        FROM
                                "
.MOD_WATCHER_TABLE_F." w,
                                "
.TOPICS_TABLE." t
                                LEFT JOIN "
.MOD_WATCHER_TABLE_T." wt
                                        ON wt.tid=t.topic_id  AND wt.uid=w.uid
                        WHERE
                                w.uid=? AND w.fid in (?) AND
                                t.forum_id=w.fid AND t.topic_time>w.mtime AND t.topic_status=0 AND
                                wt.fid IS NULL
                        GROUP BY
                                w.fid
                        "
,
                        $this->uid, $dirty
                );
                if (!($result = $this->db->sql_query($sql)))
                        message_die(GENERAL_ERROR, 'SQL error', '', __LINE__, __FILE__, $sql);
                while ($row = $this->db->sql_fetchrow($result)) {
                        $fid = $row['fid'];
                        if (!isset (www.php.net/isset)($status[$fid])) continue;
                        $status[$fid]['nnew'] = $row['nnew'];
                }
                foreach ($dirty as $fid) {
                        $st =& $status[$fid];
                        if ($st['nnew'] < 0 || $st['nmodified'] < 0) {
                                if ($st['nnew'] < 0) $st['nnew'] = 0;
                                if ($st['nmodified'] < 0) $st['nmodified'] = 0;
                        }
                        $sql = make_sql("
                                        UPDATE "
.MOD_WATCHER_TABLE_F." SET
                                                nnew=?, nmodified=?
                                        WHERE
                                                uid=? AND fid=?
                                "
,
                                $st['nnew'], $st['nmodified'], $this->uid, $fid
                        );
                        $this->db->sql_query($sql)
                                or message_die(GENERAL_ERROR, 'SQL error', '', __LINE__, __FILE__, $sql);
                }
        }
#                dump($status);
        return $status;
}
Back to top
View user's profile Send private message Send e-mail
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Sat Dec 13, 2003 12:14 pm (спустя 10 часов 13 минут)
   Post subject:
Reply with quote

Дмитрий Котеров wrote:
можно, это сэкономит быстродействие
В будущем времени ;) ?
Дмитрий Котеров wrote:
Одна из функций
Насколько я понял, эта функция собирает статистику на главной странице ? И насколько я понял, она берет данные в основном из "готовой" таблицы с результатами...
Можете пояснить, что именно хранится в таблице MOD_WATCHER_TABLE_F и что в MOD_WATCHER_TABLE_T (во второй, как я понял, хранится список модифицированных тем ?)
Дмитрий Котеров wrote:
а завтра изменилась тема, которая Вам интересна, но была вчера задруксована.
Да, пожалуй Вы правы... Я че-то об этом не подумал...
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Sun Dec 14, 2003 3:38 am (спустя 15 часов 24 минуты)
   Post subject:
Reply with quote

MOD_WATCHER_TABLE_F: хранятся пометки друксования для каждого пользователя и каждого форума (первичный ключ — UserID+ForumID). А также разные флаги для оптимизации (типа, изменилось что-то или нет с последнего раза, плюс кэш текущих значений счетчиков новых/обновленных тем).

MOD_WATCHER_TABLE_T: хранятся пометки для топиков, первичный ключ — UserID+TopicID.
Back to top
View user's profile Send private message Send e-mail
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Sun Dec 14, 2003 12:04 pm (спустя 8 часов 26 минут)
   Post subject:
Reply with quote

Я долго думал насчет Вашей системы статистики... Самое интересное это то, что мне в голову другая реализация как-то и не приходила... А способ отслеживания "новых" тем мне очень понравился :). Никогда бы не подумал...
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Sun Dec 14, 2003 8:30 pm (спустя 8 часов 25 минут)
   Post subject:
Reply with quote

К сожалению, эта реализация несколько подтормаживает. Она даже сильнее тормозит, чем ЧПУ. Были бы в MySQL триггеры — все бы сразу решилось. Так нет же их...
Back to top
View user's profile Send private message Send e-mail
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Thu Jan 08, 2004 7:57 pm (спустя 24 дня 23 часа 27 минут)
   Post subject:
Reply with quote

Дмитрий Котеров wrote:
 сдвигать метку друксования — можно, это сэкономит быстродействие.
А в этой реализации сдвигается ?

Хотя у меня был вопрос немного другой. При просмотре форума выбираются все записи из MOD_WATCHER_TABLE_T, соответствующие этому форуму и этому пользователю, или ставится какое-то ограничение, выборка идет по какому-то жесткому условию, и т.д. ?

Потому что у меня возникло только 2 варианта:
Code (SQL): скопировать код в буфер обмена
SELECT * FROM MOD_WATCHER_TABLE_T WHERE fid=? AND uid=?
Это было бы логичным.

Но есть и другой вариант, который бы выбирал только те темы, которые есть на этой странице (правда там придется немного модифицировать вывод тем, это не так важно)
Code (SQL): скопировать код в буфер обмена
SELECT * FROM MOD_WATCHER_TABLE_T WHERE tid IN(?) AND uid=?
Второй вариант будет более правильным только если количество просмотренных тем достигает хотя бы половины всех тем этого форума, и все темы не влезают на одну страницу. Как раз такой случай в этом форуме с постоянными участниками ;) (ИМХО).

P.S. Может, накладывается еще какое-нибудь ограничение в виде ограничений на последнюю дату просмотра темы, но что-то мне в голову ничего по этому поводу не приходит... Что-нибудь связанное с датой друксования форума...

P.P.S. А как там с измененными темами, которые человек еще не просмотрел, но созданы они раньше даты друксования форума (такое часто бывает с недавно зарегистрировавшимися пользователями) ? Если я правильно понимаю, они должны тоже быть "красными". Но в таком случае можно удалять записи о просмотрах темы, раньше даты последнего друксования (см. первый вопрос)(просто хранить их не имеет смысла, т.к. они по-любому считаются что уже просмотрены), тем самым в десятки раз уменьшив таблицу MOD_WATCHER_TABLE_T ! Или я опять не прав ?
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Thu Jan 08, 2004 8:14 pm (спустя 17 минут)
   Post subject:
Reply with quote

yUAC wrote:
select * from MOD_WATCHER_TABLE_T where fid=? and uid=?
Сейчас так. Такой запрос выполняется для каждой найденной ссылки (с кэшированием).
yUAC wrote:
select * from MOD_WATCHER_TABLE_T where tid in(?) and uid=?
Для этого нужно вначале выдрать из страницы все ID топиков. А вот для этого надо переписывать систему парсинга тэгов — потому что сейчас проход по HTML выполняется только один раз, а в варианте с IN() нужно как минимум 2 прохода. Собственно, об этой оптимизации я и веду речь вот уже почти полгода.
yUAC wrote:
А как там с измененными темами, которые человек еще не просмотрел, но созданы они раньше даты друксования форума
Я уже и не помню, если честно. Где-то наверху должно быть написано про это.
Back to top
View user's profile Send private message Send e-mail
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Thu Jan 08, 2004 8:23 pm (спустя 9 минут)
   Post subject:
Reply with quote

Дмитрий Котеров wrote:
Я уже и не помню, если честно. Где-то наверху должно быть написано про это.
Если это работает как я описал, то хорошая оптимизация вполне возможна !
Дмитрий Котеров wrote:
Такой запрос выполняется для каждой найденной ссылки (с кэшированием).
Какой смысл делать кэширование, если эта система является очень динамичной ?
Дмитрий Котеров wrote:
А вот для этого надо переписывать систему парсинга тэгов
Почему же ? Изменить в паре мест while на foreach, и все !
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Thu Jun 17, 2004 5:07 pm (спустя 5 месяцев 8 дней 20 часов 44 минуты)
   Post subject:
Reply with quote


М

Ветка выделена в отдельную тему «Издержки ЧПУ.»,
расположенную в форуме Предложения по организации форума (17 Июня 2004, 18:07).
Back to top
View user's profile Send private message Send e-mail
NoN
Участник форума



Joined: 26 Jul 2005
Posts: 98
Карма: -10
   поощрить/наказать

Location: SPB.RU

PostPosted: Sat Aug 06, 2005 11:32 am (спустя 1 год 1 месяц 18 дней 18 часов 24 минуты)
   Post subject:
Reply with quote

Quote:
Вы поняли неправильно. Удалять в идеале пометки вообще никогда нельзя (разве что при посещении закрытой темы). Представьте, что Вы задруксовали форум, а завтра изменилась тема, которая Вам интересна, но была вчера задруксована.

Если я, конечно, ничего не путаю.
Если я правильно понял термин "задруксовали" - отметили прочитаным, то Вы, возможно, путаете кое-что.

Если обновляется тема, то время её обновления (в стандартном phpBB её кажется нет, но в IPB таблице тем есть поле - последнее изменение. Можно добавить) будет после времени "задруксования" и её стоит рассматривать как прочитаную/непрочитаную.
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Sat Aug 06, 2005 12:24 pm (спустя 51 минуту; написано за 44 секунды)
   Post subject:
Reply with quote

А если изменилась тема, которую я ни разу не открывал? Ее, очевидно, не надо помечать непрочитанной. Вот для различения таких тем и нужно оставлять пометки. Все учтено.
Back to top
View user's profile Send private message Send e-mail
Maus
Модератор



Joined: 29 Jun 2003
Posts: 8151
Карма: 271
   поощрить/наказать

Location: пос. Омсукчан Магаданской области

PostPosted: Mon Aug 20, 2007 7:11 pm (спустя 2 года 14 дней 6 часов 47 минут)
   Post subject:
Reply with quote


М

Ветка выделена в отдельную тему «оффтопик»,
расположенную в форуме Мусоропровод (20 Августа 2007, 19:11).
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML